/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Nathan
 */

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Building {
    /* Elevator rider interface (part 2): invoked by rider threads.
    */
    private BufferedWriter writer;
            
    private ArrayList<Elevator> elevators;
    private ArrayList<Thread> elevatorThreads;
	private int numFloors;
    
    public Building(int numFloors, int numElevators, int maxOccupancy) {
        this.numFloors = numFloors;
        try {
            writer = new BufferedWriter(new FileWriter("elevator.log"));
        } catch (IOException ex) {
            Logger.getLogger(Building.class.getName()).log(Level.SEVERE, null, ex);
        }
        elevators = new ArrayList<>();
        elevatorThreads = new ArrayList<>();
        for (int i = 0; i<numElevators; i++) {
            elevators.add(new Elevator(numFloors, i+1, maxOccupancy, this));
            elevatorThreads.add(new Thread(elevators.get(i)));
            elevatorThreads.get(i).setName("E" + (i+1));
        }
        
        for (int i = 0; i<numElevators; i++) {
            elevatorThreads.get(i).start();
        }
    }
    
    /* Signal the elevator that we want to go up */
    public Elevator CallUp(int fromFloor) {
    	if (!(fromFloor > 0 && fromFloor <= numFloors)) {
    		write("Error, floor " + fromFloor + " does not exist");
    		Thread.currentThread().destroy();
    		return null;
    	}
        //Currently supports one elevator
    	//elevatorThreads.floorCall(fromFloor);
    	for(Elevator e: elevators) {
    		synchronized(e) {
	    		if((e.isIdle() || (e.isGoingUp() && e.getCurrentFloor() <= fromFloor)) && e.hasSpace()) {
	    			e.setGoingUp(true);
	    			if (e.isIdle())
	    				e.setDest(fromFloor);
	    			else if(e.getDest() < fromFloor)
	    				e.setDest(fromFloor);
	    			e.floorCall(fromFloor);
	    			
	    			if (e.hasSpace())
	    				return e;
	    		}
    		}
    	}
    	return null;
    }

    /* Signal the elevator that we want to go down */
    public Elevator CallDown(int fromFloor) {
    	if (!(fromFloor > 0 && fromFloor <= numFloors)) {
    		write("Error, floor " + fromFloor + " does not exist");
    		Thread.currentThread().destroy();
    		return null;
    	}
    	for(Elevator e: elevators) {
    		synchronized(e) {
	    		if(e.isIdle() || (!e.isGoingUp() && e.getCurrentFloor() >= fromFloor)) {
	    			e.setGoingUp(false);
	    			if (e.isIdle())
	    				e.setDest(fromFloor);
	    			else if(e.getDest() > fromFloor)
	    				e.setDest(fromFloor);
	    			e.floorCall(fromFloor);
	    			
	    			return e;
	    		}
    		}
    	}
    	return null;
    }
    
    public synchronized void write(String s) {
    	System.out.println(s);
        try {
            writer.write(s);
            writer.newLine();
            writer.flush();
        } catch (IOException ex) {
            Logger.getLogger(Building.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /* Other methods as needed goes here */
}